package ltd.sshine.tracking.web.validator;


import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>至少一个属性非空校验器</p>
 *
 * @author pzg
 * @since 2022/11/19
 */
public class NotAllNullValidator implements ConstraintValidator<NotAllNull, Object> {

    private String[] fields;
    private Set<String> ignores;

    @Override
    public void initialize(NotAllNull constraintAnnotation) {
        this.fields = constraintAnnotation.fields();
        this.ignores =Arrays.stream(constraintAnnotation.ignores()).collect(Collectors.toSet());
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            return false;
        }
        return  fields.length==0?validAll(value):validFiles(value);
    }


    private  boolean validAll(Object value){
        try {
            for (Field declaredField : value.getClass().getDeclaredFields()) {
                declaredField.setAccessible(true);
                if (declaredField.get(value) != null) {
                    return true;
                }
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return false;
    }
    private  boolean validFiles(Object value){
        Class<?> aClass = value.getClass();
      return  Arrays.stream(fields).map(f->{
          try {
              Field declaredField = aClass.getDeclaredField(f);
              declaredField.setAccessible(true);
              return declaredField;
          } catch (NoSuchFieldException e) {
              throw new RuntimeException(e);
          }
      }).anyMatch(field -> {
          try {
              return !ignores.contains(field.getName())&& field.get(value)!=null;
          } catch (IllegalAccessException e) {
              throw new RuntimeException(e);
          }
      });
    }

}
